#include "TaskQueue.hpp"
#include "MutexLock.hpp"
#include "Condition.hpp"
#include "LockGuard.hpp"

#include <iostream>

#include <queue>
using std::cout;
using std::endl;
using std::queue;

namespace wd{

TaskQueue::TaskQueue(int que_size)
:_que()
,_queSize(que_size)
,_mutex()
,_notFull(_mutex)
,_notEmpty(_mutex)
,_flag(true)
{
    
}

TaskQueue::~TaskQueue(){

}

bool TaskQueue::empty(){
    return _que.size() == 0;
}
bool TaskQueue::full(){
    return _que.size() == _queSize;
}
void TaskQueue::push(ElemType && ele){
    /* _mutex.lock(); */
    LockGuard lockguard(_mutex);
    
    while(full()){
       _notFull.wait(); 
    }
    _que.push(std::move(ele));
    
    _notEmpty.notify_one();

    /* _mutex.unlock(); */
}


ElemType TaskQueue::pop(){
   ElemType temp; 
    
    //_mutex.lock();
    LockGuard lockguard(_mutex);
    
    while(empty() && _flag){
        _notEmpty.wait();
    }
    if(_flag){
        temp = _que.front();
        _que.pop();

        _notFull.notify_one();
    }else{
        temp = nullptr;
    }
    //_mutex.unlock();
    return temp;

}

void TaskQueue::wakeup(){
    _flag = false;
    _notEmpty.notify_all();
}

}
